package algo_lignes_sites.ihm;

import algo_lignes_sites.data.Data_ls;
import algo_lignes_sites.data.pre_trt.PreTraitementInputData_ls;
import algo_lignes_sites.data.pre_trt.pre_trt_path.SimplifTracePath;
import algo_lignes_sites.io.out.DataOutput;
import algo_lignes_sites.trt.DialogTraitementLigneSite;
import commons.Constants;
import commons.errors.ErrorsHandler;
import commons.ihm.A_PanelCartoTocTools;
import commons.logs.Logger;
import commons.params_appli.ParamsAppli;
import commons.utils.UtilsFile;
import java.awt.Cursor;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;


public class MainFrameTraitementLigneSite extends javax.swing.JFrame implements Runnable {

	A_PanelCartoTocTools panelCartoTocTools;
	Data_ls data;

	private String titreBase;

    public MainFrameTraitementLigneSite() {
        initComponents();
		panelCartoTocTools = new PanelCartoTocTools_ls();
		panelContainer_CTT.add(panelCartoTocTools, java.awt.BorderLayout.CENTER);

		panel_ModeInteract.setVisible(false);

		tf_RepBase.setText(ParamsAppli.getParam("common.REPERTOIRE_DONNEES"));
		initListeRepertoiresData();

		titreBase = "Autogene " + Constants.VERSION_AUTOGENE + " : Ligne-Noeuds";
		
		if (ParamsAppli.hasLimitationForLS)
			titreBase = "DEMO " + titreBase;
		
		// Affichage régulier de la consommation de mémoire
		Timer timer=new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {showMemoryUsage();}
		}, 0, 1000);
		
		Logger.keepLogInRAM();
    }

	private void showMemoryUsage() {
		// Mémoire totale allouée
		long totalMemory = Runtime.getRuntime().totalMemory(); 
		// Mémoire utilisée
		long currentMemory = totalMemory-Runtime.getRuntime().freeMemory();
		
		double prct = 100.0 * currentMemory / totalMemory;
		
		//String newtitre = titreBase + "  -  Mémoire : " + (int)(currentMemory / (1024.0*1024.0)) + " / "  + (int)(totalMemory / (1024.0*1024.0)) + " Mio  (" + (int)prct + " %)";
		String newtitre = titreBase + "  -  Mémoire : " + (int)(currentMemory / (1000.0*1000.0)) + " / "  + (int)(totalMemory / (1000.0*1000.0)) + " Mo";
		
		this.setTitle(newtitre);
	}

	private void initListeRepertoiresData() {
		combo_JeuDonnees.removeAllItems();
		combo_JeuDonnees.addItem("");
		File rep = new File (tf_RepBase.getText());
		File[] listeAllFiles = rep.listFiles();
		if (listeAllFiles != null) {
			for (File f : listeAllFiles) {
				if (f.isDirectory()) {
					combo_JeuDonnees.addItem(f.getName());
				}
			}
		}
	}

	// Demande de changement d'échelle de la carte : certaines données, telles que les épaisseurs de lignes
	//  et donc en conséquence les poids spéciaux de répulsion près des intersections etc.
	//  sont à recalculer
	private void updateEchelleCarte() {
		if (data != null)
			data.setEchelleCarteCourante(slider_Echelle.getValue());
		panelCartoTocTools.setEchelleCarteCourante(slider_Echelle.getValue());
		panelCartoTocTools.repaintCarto();
	}

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        panelContainer_CTT = new javax.swing.JPanel();
        panel_Controls = new javax.swing.JPanel();
        combo_JeuDonnees = new javax.swing.JComboBox();
        button_ChangeRepBase = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        tf_RepBase = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        button_ChargerDonnees = new javax.swing.JButton();
        button_LanceGeneralisation = new javax.swing.JButton();
        button_SaveAndQuit = new javax.swing.JButton();
        cb_ModeDebug = new javax.swing.JCheckBox();
        panel_ModeInteract = new javax.swing.JPanel();
        toggle_StartStop = new javax.swing.JToggleButton();
        button_Step = new javax.swing.JButton();
        button_ComputeForce = new javax.swing.JButton();
        slider_Echelle = new javax.swing.JSlider();
        button_PostTrt = new javax.swing.JButton();
        button_ShowLogs = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        panelContainer_CTT.setLayout(new java.awt.BorderLayout());

        combo_JeuDonnees.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        combo_JeuDonnees.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        combo_JeuDonnees.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                combo_JeuDonneesActionPerformed(evt);
            }
        });

        button_ChangeRepBase.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        button_ChangeRepBase.setText("...");
        button_ChangeRepBase.setToolTipText("Changer le répertoire de base");
        button_ChangeRepBase.setMargin(new java.awt.Insets(0, 4, 0, 4));
        button_ChangeRepBase.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_ChangeRepBaseActionPerformed(evt);
            }
        });

        jLabel2.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        jLabel2.setText("Rép. de base : ");

        tf_RepBase.setEditable(false);
        tf_RepBase.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        tf_RepBase.setText("jTextField1");
        tf_RepBase.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(102, 102, 102)));

        jLabel3.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        jLabel3.setText("Projets :");

        button_ChargerDonnees.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        button_ChargerDonnees.setText("Re-charge données + params");
        button_ChargerDonnees.setMargin(new java.awt.Insets(2, 4, 2, 4));
        button_ChargerDonnees.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_ChargerDonneesActionPerformed(evt);
            }
        });

        button_LanceGeneralisation.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        button_LanceGeneralisation.setText("Lance traitement");
        button_LanceGeneralisation.setMargin(new java.awt.Insets(2, 4, 2, 4));
        button_LanceGeneralisation.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_LanceGeneralisationActionPerformed(evt);
            }
        });

        button_SaveAndQuit.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        button_SaveAndQuit.setText("Sauvegarde résultat");
        button_SaveAndQuit.setMargin(new java.awt.Insets(2, 4, 2, 4));
        button_SaveAndQuit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_SaveAndQuitActionPerformed(evt);
            }
        });

        cb_ModeDebug.setText("<html>Mode <br>manuel</html>");
        cb_ModeDebug.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cb_ModeDebugActionPerformed(evt);
            }
        });

        toggle_StartStop.setText("Start/Stop");
        toggle_StartStop.setMargin(new java.awt.Insets(2, 4, 2, 4));
        toggle_StartStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                toggle_StartStopActionPerformed(evt);
            }
        });

        button_Step.setText("Step");
        button_Step.setMargin(new java.awt.Insets(2, 4, 2, 4));
        button_Step.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_StepActionPerformed(evt);
            }
        });

        button_ComputeForce.setText("Forces");
        button_ComputeForce.setMargin(new java.awt.Insets(2, 4, 2, 4));
        button_ComputeForce.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_ComputeForceActionPerformed(evt);
            }
        });

        slider_Echelle.setToolTipText("Changement manuel de l'échelle courante des données");
        slider_Echelle.setMinimumSize(new java.awt.Dimension(36, 20));
        slider_Echelle.setPreferredSize(new java.awt.Dimension(200, 20));
        slider_Echelle.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                slider_EchelleStateChanged(evt);
            }
        });

        javax.swing.GroupLayout panel_ModeInteractLayout = new javax.swing.GroupLayout(panel_ModeInteract);
        panel_ModeInteract.setLayout(panel_ModeInteractLayout);
        panel_ModeInteractLayout.setHorizontalGroup(
            panel_ModeInteractLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panel_ModeInteractLayout.createSequentialGroup()
                .addComponent(toggle_StartStop)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(button_Step)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(button_ComputeForce)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addComponent(slider_Echelle, javax.swing.GroupLayout.DEFAULT_SIZE, 231, Short.MAX_VALUE)
        );
        panel_ModeInteractLayout.setVerticalGroup(
            panel_ModeInteractLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panel_ModeInteractLayout.createSequentialGroup()
                .addGroup(panel_ModeInteractLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(toggle_StartStop)
                    .addComponent(button_Step)
                    .addComponent(button_ComputeForce, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(slider_Echelle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        button_PostTrt.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        button_PostTrt.setText("Post-trt");
        button_PostTrt.setMargin(new java.awt.Insets(2, 4, 2, 4));
        button_PostTrt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_PostTrtActionPerformed(evt);
            }
        });

        button_ShowLogs.setFont(new java.awt.Font("Trebuchet MS", 0, 11)); // NOI18N
        button_ShowLogs.setText("Logs...");
        button_ShowLogs.setMargin(new java.awt.Insets(2, 4, 2, 4));
        button_ShowLogs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_ShowLogsActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout panel_ControlsLayout = new javax.swing.GroupLayout(panel_Controls);
        panel_Controls.setLayout(panel_ControlsLayout);
        panel_ControlsLayout.setHorizontalGroup(
            panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panel_ControlsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panel_ControlsLayout.createSequentialGroup()
                        .addComponent(tf_RepBase)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(button_ChangeRepBase))
                    .addGroup(panel_ControlsLayout.createSequentialGroup()
                        .addComponent(combo_JeuDonnees, javax.swing.GroupLayout.PREFERRED_SIZE, 313, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(button_ChargerDonnees, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(panel_ControlsLayout.createSequentialGroup()
                        .addComponent(button_LanceGeneralisation, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(button_PostTrt))
                    .addComponent(button_SaveAndQuit, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(button_ShowLogs)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
                .addComponent(cb_ModeDebug, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panel_ModeInteract, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        panel_ControlsLayout.setVerticalGroup(
            panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panel_ControlsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(panel_ModeInteract, javax.swing.GroupLayout.Alignment.LEADING, 0, 0, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, panel_ControlsLayout.createSequentialGroup()
                        .addGroup(panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(tf_RepBase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(button_ChangeRepBase)
                            .addComponent(button_LanceGeneralisation)
                            .addComponent(button_PostTrt))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(combo_JeuDonnees, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(button_ChargerDonnees)
                            .addComponent(button_SaveAndQuit)
                            .addComponent(jLabel3)))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, panel_ControlsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(cb_ModeDebug, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(button_ShowLogs)))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(panel_Controls, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(panelContainer_CTT, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(panel_Controls, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panelContainer_CTT, javax.swing.GroupLayout.DEFAULT_SIZE, 652, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void toggle_StartStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_toggle_StartStopActionPerformed
		if (toggle_StartStop.isSelected())
			startAnimate();
		else
			stopAnimate();
}//GEN-LAST:event_toggle_StartStopActionPerformed

	private void button_StepActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_StepActionPerformed

		if (bIsAnimating) toggle_StartStop.setSelected(false);
		if (data==null)	return;
		step();
}//GEN-LAST:event_button_StepActionPerformed

	private void button_ComputeForceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_ComputeForceActionPerformed
		if (bIsAnimating) toggle_StartStop.setSelected(false);
		if (data==null)	return;
		computeForce();
		panelCartoTocTools.repaintCarto();
}//GEN-LAST:event_button_ComputeForceActionPerformed

	private void button_LanceGeneralisationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_LanceGeneralisationActionPerformed
		
		if (bIsAnimating) toggle_StartStop.setSelected(false);
		if (data==null)	return;
		
		DialogTraitementLigneSite f = new DialogTraitementLigneSite(data);
		f.setModal(true);
		f.setVisible(true);
		slider_Echelle.setValue((int) (1/data.params.echelleCible));
		panelCartoTocTools.repaintCarto();
	}//GEN-LAST:event_button_LanceGeneralisationActionPerformed

	private void button_ChargerDonneesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_ChargerDonneesActionPerformed
		if (combo_JeuDonnees.getSelectedItem()==null || combo_JeuDonnees.getSelectedItem().equals("")) return;
		
		// on commence a arreter l'animation éventuellement en cours
		if (bIsAnimating) toggle_StartStop.setSelected(false);

		String fullPath_JeuDonnee = tf_RepBase.getText() + "\\" + combo_JeuDonnees.getSelectedItem();
		String fullPath_RepFichierSource = fullPath_JeuDonnee + "\\" + ParamsAppli.getParam("common.SOUS_REP_FICHIERS_SOURCE");

		ErrorsHandler.reinitErrors();
		
		// reinit des logs en RAM, pour éviter une fuite de mémoire en cas de très nombreux lancements de traitements
		Logger.resetLogInRAM();

		try {
			this.setCursor(Cursor.WAIT_CURSOR);
			Data_ls data_new = PreTraitementInputData_ls.createDataFromDirectory(this, fullPath_RepFichierSource);
			this.setCursor(Cursor.DEFAULT_CURSOR);

			if (ErrorsHandler.isThereErrors()) {
				ErrorsHandler.showErrors();
			}

			if (data_new != null) {
				data = data_new;
				panelCartoTocTools.setData(data);

				titreBase = "Autogene " + Constants.VERSION_AUTOGENE + " : Ligne-Noeuds    paramètres : " + data.params.nomParam;

				// On redefinit la borne max du slider d'échelle manuelle
				slider_Echelle.setMinimum(10);
				slider_Echelle.setMaximum((int) (1/data.params.echelleCible));
				slider_Echelle.setValue((int) (1/data.params.echelleInit));
				updateEchelleCarte(); //ca met à jour les dimensions réelles des objets du data
				
				// apres un eventuel post traitement, ces boutons ont été désactivés : on les reactive car les données sont nouvelles
				button_LanceGeneralisation.setEnabled(true);
				toggle_StartStop.setEnabled(true);
				button_Step.setEnabled(true);
				button_ComputeForce.setEnabled(true);
			}
		} catch (OutOfMemoryError t) {
			ErrorsHandler.addError("Exception OutOfMemory durant le prétraitement : relancer l'application avec des paramètres -Xms et -Xmx plus élevés");
			ErrorsHandler.showErrors();
			data = null;
		}

		panelCartoTocTools.repaintCarto();
	}//GEN-LAST:event_button_ChargerDonneesActionPerformed

	private void button_SaveAndQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_SaveAndQuitActionPerformed
		if (bIsAnimating) toggle_StartStop.setSelected(false);

		// Aucune donnée chargée ?
		if (data==null)	return;

		String path_JeuDonnees = tf_RepBase.getText() + "\\" + combo_JeuDonnees.getSelectedItem();
		
		// On demande dans quel sous répertoire écrire les données = nom du traitement
		//  on propose par défaut un nom pratique
		String nomTrt = "<DATE> LIGNESITE (" + data.params.nomParam + ")";
		nomTrt = JOptionPane.showInputDialog(this, "Indiquer le nom du traitement (il doit constituer un nom de répertoire valide)", nomTrt);
		
		// Export annulé par l'utilisateur ?
		if (nomTrt==null)
			return;
		

		// On commence par un post traitement
		button_PostTrtActionPerformed(null);
		
		
		// Remplacement de l'éventuelle balise <DATE>
		nomTrt = nomTrt.replaceAll("<DATE>", new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date()));
		
		// Vérification de la validité du nom choisi
		if (!UtilsFile.isFileNameValide(nomTrt)) {
			JOptionPane.showMessageDialog(this, "Nom de traitement incorrect : doit constituer un nom de répertoire valide !", "Erreur", JOptionPane.ERROR_MESSAGE);
			return;
		}

		String path_Export = path_JeuDonnees + "\\" + ParamsAppli.getParam("common.SOUS_REP_FICHIERS_TRAITES") + "\\" + nomTrt;

		this.setCursor(Cursor.WAIT_CURSOR);
		DataOutput.writeResult(data, path_Export);
		this.setCursor(Cursor.DEFAULT_CURSOR);

		//this.setVisible(false);
		//this.dispose();
	}//GEN-LAST:event_button_SaveAndQuitActionPerformed

	private void combo_JeuDonneesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_combo_JeuDonneesActionPerformed
		button_ChargerDonneesActionPerformed(null);
	}//GEN-LAST:event_combo_JeuDonneesActionPerformed

	private void slider_EchelleStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_slider_EchelleStateChanged
		boolean bIsAnimating_ = isAnimating();
		if (bIsAnimating) stopAnimate();
		if (data==null) return;

		updateEchelleCarte();

		if (bIsAnimating_) startAnimate();
	}//GEN-LAST:event_slider_EchelleStateChanged

	private void button_ChangeRepBaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_ChangeRepBaseActionPerformed
		// Changement du répertoire de base des fichiers
		JFileChooser jfc = new JFileChooser();
		jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		jfc.setCurrentDirectory(new File(tf_RepBase.getText()));
		int returnVal = jfc.showDialog(this, "Choisir ce répertoire");
		if(returnVal == JFileChooser.APPROVE_OPTION) {
			tf_RepBase.setText(jfc.getSelectedFile().getPath());
			initListeRepertoiresData();
		}
	}//GEN-LAST:event_button_ChangeRepBaseActionPerformed

	private void cb_ModeDebugActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cb_ModeDebugActionPerformed
		panel_ModeInteract.setVisible(cb_ModeDebug.isSelected());
	}//GEN-LAST:event_cb_ModeDebugActionPerformed

    private void button_PostTrtActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_PostTrtActionPerformed
		if (bIsAnimating) toggle_StartStop.setSelected(false);
		if (data==null) return;
		
		data.postTraitement();
		panelCartoTocTools.repaintCarto();
		
		
		// apres le post traitement, il n'est plus possible de relancer un traitement
		button_LanceGeneralisation.setEnabled(false);
		toggle_StartStop.setEnabled(false);
		button_Step.setEnabled(false);
		button_ComputeForce.setEnabled(false);
		
    }//GEN-LAST:event_button_PostTrtActionPerformed

    private void button_ShowLogsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_button_ShowLogsActionPerformed
        Logger.showLogInRAM(this);
    }//GEN-LAST:event_button_ShowLogsActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton button_ChangeRepBase;
    private javax.swing.JButton button_ChargerDonnees;
    private javax.swing.JButton button_ComputeForce;
    private javax.swing.JButton button_LanceGeneralisation;
    private javax.swing.JButton button_PostTrt;
    private javax.swing.JButton button_SaveAndQuit;
    private javax.swing.JButton button_ShowLogs;
    private javax.swing.JButton button_Step;
    private javax.swing.JCheckBox cb_ModeDebug;
    private javax.swing.JComboBox combo_JeuDonnees;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel panelContainer_CTT;
    private javax.swing.JPanel panel_Controls;
    private javax.swing.JPanel panel_ModeInteract;
    private javax.swing.JSlider slider_Echelle;
    private javax.swing.JTextField tf_RepBase;
    private javax.swing.JToggleButton toggle_StartStop;
    // End of variables declaration//GEN-END:variables


	Thread thread;
	private boolean bIsAnimating = false;
	
	// TODO_KO ALGO : rendre parametrable
	private double DT = 1.0 / 100.0; // = 1/100 sec


	public boolean isAnimating() {
		return bIsAnimating;
	}

	public void startAnimate() {
		if (bIsAnimating) return;
		bIsAnimating = true;
	    thread = new Thread(this);
	    thread.start();
	}

	public void stopAnimate() {
		if (bIsAnimating) {
			try {
			    bIsAnimating = false;
				thread.join();
			} catch (InterruptedException e) {
			}
		}
		thread = null;
	}

	@Override
	public void run() {
		int sleep_time_ms;
		while (bIsAnimating){
			try {
			    sleep_time_ms = (int) (DT*1000);
				Thread.sleep((long)(sleep_time_ms));
				step();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void computeForce() {
		if (data==null) return;
		data.computeForces();
	}

	public void step() {
	    if (data==null) return;
		data.step("");
	    panelCartoTocTools.repaint();
	}

}
